using UnityEngine;
using Spine.Unity;
using DG.Tweening;
using System.Linq;

[ExecuteAlways]
[RequireComponent(typeof(SkeletonRenderer))]
public class SpineOutlineSmoothToggle : MonoBehaviour {
    [Header("Outline 配置")]
    public Color outlineColor = Color.red;
    [Range(0f, 8f)] public float maxOutlineWidth = 3f;
    [Tooltip("开/关 描边效果")]
    public bool enableOutline = false;

    [Tooltip("描边宽度过渡时长（秒）")]
    public float transitionDuration = 0.5f;
    [Tooltip("描边宽度结束时长（秒）")]
    public float transitionDurationEnd = 0.5f;

    SkeletonRenderer sr;
    Material[] originalMats;   // 原始材质
    Material[] outlineMats;    // 克隆后的 Outline 材质

    bool lastState;            // 记录上一次的 enableOutline 值
    Sequence tweenSequence;    // 用于 “开/关 描边宽度过度” 的 Tween
    Sequence flickerSequence;  // 用于 “闪烁” 的 Tween

    void Awake() {
        InitMaterials();
        // 强制触发一次 Update 里的逻辑
        lastState = !enableOutline;
    }

    void OnValidate() {
        InitMaterials();
        lastState = !enableOutline;
    }

    void Update() {
        if (lastState == enableOutline) return;
        lastState = enableOutline;

        // 杀掉所有正在跑的 Tween
        tweenSequence?.Kill();
        flickerSequence?.Kill();

        if (enableOutline) StartEnableOutlineTween();
        else             StartDisableOutlineTween();
    }

    void InitMaterials() {
        if (sr != null) return;
        sr = GetComponent<SkeletonRenderer>();

        var atlasAssets = sr.skeletonDataAsset.atlasAssets;
        originalMats = atlasAssets.Select(a => a.PrimaryMaterial).ToArray();
        outlineMats  = new Material[originalMats.Length];

        for (int i = 0; i < originalMats.Length; i++) {
            Shader outlineShader = Shader.Find("Spine/Outline/Skeleton");
            var m = new Material(outlineShader) {
                name = originalMats[i].name + " (OutlineClone)"
            };
            m.CopyPropertiesFromMaterial(originalMats[i]);
            m.SetColor("_OutlineColor", outlineColor);
            m.SetFloat("_OutlineWidth", 0f);
            outlineMats[i] = m;
        }
    }

    void StartEnableOutlineTween() {
        sr.CustomMaterialOverride.Clear();
        for (int i = 0; i < originalMats.Length; i++) {
            sr.CustomMaterialOverride[originalMats[i]] = outlineMats[i];
        }

        // 先做描边宽度平滑过渡
        tweenSequence = DOTween.Sequence();
        foreach (var m in outlineMats) {
            tweenSequence.Join(
                m.DOFloat(maxOutlineWidth, "_OutlineWidth", transitionDuration)
                 .SetEase(Ease.OutQuad)
            );
        }
        // 完成后启动闪烁
        tweenSequence.OnComplete(StartOutlineFlicker);
    }

    void StartOutlineFlicker() {
        // 闪烁：宽度在 maxOutlineWidth <-> 0 之间来回，半周期 0.05s，循环
        flickerSequence = DOTween.Sequence();
        foreach (var m in outlineMats) {
            flickerSequence.Join(
                m.DOFloat(0f, "_OutlineWidth", 0.5f)
                 .From(maxOutlineWidth)
                 .SetEase(Ease.Linear)
                 .SetLoops(-1, LoopType.Yoyo)
            );
        }
    }

    void StartDisableOutlineTween() {
        // 先杀掉闪烁
        flickerSequence?.Kill();
        // 再平滑过渡回 0，并在完成后清除覆盖材质
        tweenSequence = DOTween.Sequence();
        foreach (var m in outlineMats) {
            tweenSequence.Join(
                m.DOFloat(0f, "_OutlineWidth", transitionDurationEnd)
                 .SetEase(Ease.InQuad)
            );
        }
        tweenSequence.OnComplete(() => sr.CustomMaterialOverride.Clear());
    }

    /// <summary>
    /// 外部调用接口
    /// </summary>
    public void setEnableOutline(bool _enableOutline) {
        enableOutline = _enableOutline;
    }
}